/**
 * Adapted from code by Neil Coffey.
 * 
 * Here, we are implementing a simple latch class in Java - there are built-in
 * latch operations to do the same thing, but this shows you how you can use
 * wait() and notify() to communicate between threads.
 * 
 * Internally, all we have is a simple counter that decrements until all 
 * threads have completed their work, at which point notify() is called to
 * unblock the wait() operation.  This is more economical than polling, 
 * which wastes CPU, etc.
 * 
 * Also, note that the latch synchronizes on an arbitrary object - this is
 * one of the requirements of synchronization (must synchronize on an object
 * as opposed to a value e.g. a primitive data type).
 * 
 * GNU General Public License v3, February 2011.
 * 
 * @author Adam Steinberger
 * 
 * This file is part of jSynthesizer.
 * 
 * jSynthesizer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * jSynthesizer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with jSynthesizer.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Please direct all inquiries about jSynthesizer to the author:
 * Adam Steinberger, asteinberger@frontier.com, http://www.amsteinberger.com/
 */

public class Latch {
	
	private final Object synchObj = new Object();
	private int count;
	
	public Latch(int numThreads) {
		synchronized (synchObj) {
			this.count = numThreads;
		}
	}
  
  // call this on the main thread while the background threads
  // complete their work
  public void awaitZero() throws InterruptedException {
    synchronized (synchObj) {
      while (count > 0) {
        synchObj.wait();
      }
    }
  }
  
  // call this when a thread completes its work
  public void countDown() {
    synchronized (synchObj) {
      if (--count <= 0) {
        synchObj.notifyAll();
      }
    }
  }
}
